package com.bj58.mis.apm.collector;

import com.bj58.mis.apm.client.core.ApmLogEntity;
import com.bj58.mis.apm.client.core.AppNodeContext;
import com.bj58.mis.apm.client.core.BaseCollectLog;
import com.bj58.mis.apm.client.transfer.Transfer;
import com.bj58.mis.apm.client.transfer.TransferFactory;
import com.bj58.mis.apm.processor.Prosessor;
import com.bj58.mis.apm.processor.ProsessorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

public abstract class BaseCollector<CollectLog extends BaseCollectLog> implements Collector<CollectLog>{

    private static ThreadPoolExecutor executor;
    static {
        executor =  new ThreadPoolExecutor(10, 10,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(1024*10));
    }

    protected Logger logger = LoggerFactory.getLogger(this.getClass());


    private String type;
    @Override
    public void setType(String type) {
        this.type = type;
    }
    @Override
    public String getType() {
        return this.type;
    }


    @Override
    public void collect(final CollectLog collectLog) {
        if(isEnable()){
            try{
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        collectHandle(collectLog);
                    }
                });
            }catch (RejectedExecutionException e){
                logger.warn("日志采集任务队列已满，丢失日志信息: {}", collectLog.toString());
            }catch (Exception e){
                logger.error(e.toString());
            }
        }else {
            logger.debug("日志采集器 type:{}, class:{} is not enable", this.getType(), this.getClass());
        }
    }

    private boolean isEnable(){
        boolean defaultEnable = AppNodeContext.getBooleanValue("collector.enable", false);
        return AppNodeContext.getBooleanValue("collector."+this.getType()+".enable", defaultEnable);
    }

    protected void collectHandle(final CollectLog collectLog){
        logger.info("collector type: {}, content: {}", collectLog.getCollectType(), collectLog.toString());
        Prosessor prosessor = ProsessorFactory.buildProsessor(collectLog.getCollectType());
        if(prosessor==null){
            logger.error("not found prosessor for collect type:{}", collectLog.getCollectType());
            return;
        }
        ApmLogEntity entity = prosessor.prosess(collectLog);

        Transfer transfer = TransferFactory.buildTransfer(collectLog.getCollectType());
        if(transfer==null){
            logger.error("not found transfer for collect type:{}", collectLog.getCollectType());
            return;
        }
        transfer.transfer(entity);
    }

}
